home *** CD-ROM | disk | FTP | other *** search
- ; mode13h v0.90ß released 11-01-94
- ;
- ; 32 bit mode 13h graphics routines
- ; by Voltaire/OTM
- ; Copyright (C) 1994 Zach Mortensen
- ;
- ; email -
- ; mortens1@nersc.gov
- ;
- ; NOTE - These routines are designed to operate in the FLAT MEMORY
- ; MODEL ONLY! Therefore, you HAVE to be using protected mode to use
- ; them. If you're writing 32 bit code and NOT using protected mode,
- ; you should be slapped for your laziness and lack of foresight.
- ; Go spend $200 and buy Watcom C++ v10.0, it ROCKS, and it comes with
- ; DOS4GW, Rational Systems' 32 bit DOS extender. Will these routines
- ; work with Tran's PMODE? I DON'T KNOW. I picked up Tran's code long
- ; ago and found it impossible to use from within C++. I write all of
- ; my code in C++ with the exception of speed critical things like
- ; graphics primitives, and extremely low level code such as sound
- ; routines, which I do in assembler; so I never really gave PMODE
- ; much of a chance (sorry, Tran).
- ;
- ; DISCLAIMER - I am not an assembler programmer. I do not profess to
- ; be an assembler programmer. This code is all original. This code
- ; is all assembler. Therefore, this code CONTAINS SOME BUGS. I AM
- ; AWARE OF THAT. If you find any (and you will), please let me know.
- ; As far as optimization goes, I'm sure I've done a few things wrong
- ; here and there, but on the whole this is some pretty fast code. If
- ; you have any ideas on how to further optimize, please let me know
- ; as well.
- ;
-
-
- .386p
-
- .code
-
- ; Data goes here (in the CODE segment?!?! AAAAAAAAARRRGH!!)
-
-
- vidSeg dd 000A0000h
- virtPage dd ?
- curPage dd ?
-
- ; data for the triangle routines
-
- lEdge dd 200 dup(0)
- rEdge dd 200 dup(0)
- lColor dd 200 dup(0)
- rColor dd 200 dup(0)
-
- xTop dd 0
- yTop dd 0
- cTop dd 0
- xMid dd 0
- yMid dd 0
- cMid dd 0
- xBot dd 0
- yBot dd 0
- cBot dd 0
-
- rCount dd 0
-
- xBres dd 0
- yBres dd 0
- cBres dd 0
-
- dxdy dd 0
-
- ; stuff for the regHline routine
-
- color dd 0
- scanLine dd 0
- rhlColor dd 0
-
- ; for tDrawBitmap routine
-
- sPos dd 0
- dPos dd 0
- xOffset dd 0
- yOffset dd 0
- oWidth dd 0 ; original width
- oHeight dd 0 ; original height
- nWidth dd 0 ; new width
- nHeight dd 0 ; new height
-
- ; table of colors (dwords) so we don't have to calculate them
- ; every time
-
- ; I never could get this to work the way I wanted it to...;)
-
- dwColor dd 000000000h
- dd 001010101h, 002020202h, 003030303h, 004040404h
- dd 005050505h, 006060606h, 007070707h, 008080808h
- dd 009090909h, 00A0A0A0Ah, 00B0B0B0Bh, 00C0C0C0Ch
- dd 00D0D0D0Dh, 00E0E0E0Eh, 00F0F0F0Fh, 010101010h
- dd 011111111h, 012121212h, 013131313h, 014141414h
- dd 015151515h, 016161616h, 017171717h, 018181818h
- dd 019191919h, 01A1A1A1Ah, 01B1B1B1Bh, 01C1C1C1Ch
- dd 01D1D1D1Dh, 01E1E1E1Eh, 01F1F1F1Fh, 020202020h
- dd 021212121h, 022222222h, 023232323h, 024242424h
- dd 025252525h, 026262626h, 027272727h, 028282828h
- dd 029292929h, 02A2A2A2Ah, 02B2B2B2Bh, 02C2C2C2Ch
- dd 02D2D2D2Dh, 02E2E2E2Eh, 02F2F2F2Fh, 030303030h
- dd 031313131h, 032323232h, 033333333h, 034343434h
- dd 035353535h, 036363636h, 037373737h, 038383838h
- dd 039393939h, 03A3A3A3Ah, 03B3B3B3Bh, 03C3C3C3Ch
- dd 03D3D3D3Dh, 03E3E3E3Eh, 03F3F3F3Fh, 040404040h
- dd 041414141h, 042424242h, 043434343h, 044444444h
- dd 045454545h, 046464646h, 047474747h, 048484848h
- dd 049494949h, 04A4A4A4Ah, 04B4B4B4Bh, 04C4C4C4Ch
- dd 04D4D4D4Dh, 04E4E4E4Eh, 04F4F4F4Fh, 050505050h
- dd 051515151h, 052525252h, 053535353h, 054545454h
- dd 055555555h, 056565656h, 057575757h, 058585858h
- dd 059595959h, 05A5A5A5Ah, 05B5B5B5Bh, 05C5C5C5Ch
- dd 05D5D5D5Dh, 05E5E5E5Eh, 05F5F5F5Fh, 060606060h
- dd 061616161h, 062626262h, 063636363h, 064646464h
- dd 065656565h, 066666666h, 067676767h, 068686868h
- dd 069696969h, 06A6A6A6Ah, 06B6B6B6Bh, 06C6C6C6Ch
- dd 06D6D6D6Dh, 06E6E6E6Eh, 06F6F6F6Fh, 070707070h
- dd 071717171h, 072727272h, 073737373h, 074747474h
- dd 075757575h, 076767676h, 077777777h, 078787878h
- dd 079797979h, 07A7A7A7Ah, 07B7B7B7Bh, 07C7C7C7Ch
- dd 07D7D7D7Dh, 07E7E7E7Eh, 07F7F7F7Fh, 080808080h
- dd 081818181h, 082828282h, 083838383h, 084848484h
- dd 085858585h, 086868686h, 087878787h, 088888888h
- dd 089898989h, 08A8A8A8Ah, 08B8B8B8Bh, 08C8C8C8Ch
- dd 08D8D8D8Dh, 08E8E8E8Eh, 08F8F8F8Fh, 090909090h
- dd 091919191h, 092929292h, 093939393h, 094949494h
- dd 095959595h, 096969696h, 097979797h, 098989898h
- dd 099999999h, 09A9A9A9Ah, 09B9B9B9Bh, 09C9C9C9Ch
- dd 09D9D9D9Dh, 09E9E9E9Eh, 09F9F9F9Fh, 0A0A0A0A0h
- dd 0A1A1A1A1h, 0A2A2A2A2h, 0A3A3A3A3h, 0A4A4A4A4h
- dd 0A5A5A5A5h, 0A6A6A6A6h, 0A7A7A7A7h, 0A8A8A8A8h
- dd 0A9A9A9A9h, 0AAAAAAAAh, 0ABABABABh, 0ACACACACh
- dd 0ADADADADh, 0AEAEAEAEh, 0AFAFAFAFh, 0B0B0B0B0h
- dd 0B1B1B1B1h, 0B2B2B2B2h, 0B3B3B3B3h, 0B4B4B4B4h
- dd 0B5B5B5B5h, 0B6B6B6B6h, 0B7B7B7B7h, 0B8B8B8B8h
- dd 0B9B9B9B9h, 0BABABABAh, 0BBBBBBBBh, 0BCBCBCBCh
- dd 0BDBDBDBDh, 0BEBEBEBEh, 0BFBFBFBFh, 0C0C0C0C0h
- dd 0C1C1C1C1h, 0C2C2C2C2h, 0C3C3C3C3h, 0C4C4C4C4h
- dd 0C5C5C5C5h, 0C6C6C6C6h, 0C7C7C7C7h, 0C8C8C8C8h
- dd 0C9C9C9C9h, 0CACACACAh, 0CBCBCBCBh, 0CCCCCCCCh
- dd 0CDCDCDCDh, 0CECECECEh, 0CFCFCFCFh, 0D0D0D0D0h
- dd 0D1D1D1D1h, 0D2D2D2D2h, 0D3D3D3D3h, 0D4D4D4D4h
- dd 0D5D5D5D5h, 0D6D6D6D6h, 0D7D7D7D7h, 0D8D8D8D8h
- dd 0D9D9D9D9h, 0DADADADAh, 0DBDBDBDBh, 0DCDCDCDCh
- dd 0DDDDDDDDh, 0DEDEDEDEh, 0DFDFDFDFh, 0E0E0E0E0h
- dd 0E1E1E1E1h, 0E2E2E2E2h, 0E3E3E3E3h, 0E4E4E4E4h
- dd 0E5E5E5E5h, 0E6E6E6E6h, 0E7E7E7E7h, 0E8E8E8E8h
- dd 0E9E9E9E9h, 0EAEAEAEAh, 0EBEBEBEBh, 0ECECECECh
- dd 0EDEDEDEDh, 0EEEEEEEEh, 0EFEFEFEFh, 0F0F0F0F0h
- dd 0F1F1F1F1h, 0F2F2F2F2h, 0F3F3F3F3h, 0F4F4F4F4h
- dd 0F5F5F5F5h, 0F6F6F6F6h, 0F7F7F7F7h, 0F8F8F8F8h
- dd 0F9F9F9F9h, 0FAFAFAFAh, 0FBFBFBFBh, 0FCFCFCFCh
- dd 0FDFDFDFDh, 0FEFEFEFEh, 0FFFFFFFFh
-
-
-
-
- ; Code starts here
-
- ;----------------------------------------------
- ; void setMode13h(char *vPage)
- ;----------------------------------------------
- ;
- ; Sets the video mode to 320x200x256 (REAL hard), and sets up page flipping,
- ; if you want to use it. Sometimes (e.g. texture mappint) it's faster to
- ; write to the VGA one pixel at a time than it is to flip pages...don't ask
- ; me why.
- ;
- ; vPage = pointer to a buffer YOU have already allocated, better make it
- ; 64000 bytes (320x200) ... or MORE if you are in a generous mood. I do this
- ; so you can access the virtual page from higher level code if you wish.
- ; The virtual page facilitates off screen drawing (should you set the active
- ; page to pVirtual (or 1)), which eliminates screen flicker and in most cases
- ; makes your animation appear to be smoother. The virtual page tends to slow
- ; down gouraud shading and other drawing operations that write to the VGA
- ; one pixel at a time and do some calculating in between pixels.
-
- sm13Stack struc
- dd ?,? ; ebp, edi
- dd ? ; caller
- vPage dd ? ; pointer to virtual page
- sm13Stack ends
-
- public setMode13h
-
- setMode13h proc
-
- push ebp
- push edi
- mov ebp, esp
-
- mov eax, 13h
- int 10h
-
- mov eax, [ebp].vPage
- mov virtPage, eax
- mov eax, vidSeg
- mov curPage, eax
-
- mov eax, 0
- mov edi, virtPage
- mov ecx, 16000
- rep stosd
-
- mov edi, vidSeg
- mov ecx, 16000
- rep stosd
-
- pop edi
- pop ebp
-
- ret 4
-
- setMode13h endp
-
- ;--------------------
- ; void textMode(void)
- ;--------------------
- ;
- ; gets you back to 80x25...
- ;
-
- public textMode
-
- textMode proc
-
- mov eax, 3
- int 10h
-
- ret
-
- textMode endp
-
- ;--------------------------------------
- ;void setActivePage(int page)
- ;--------------------------------------
- ;
- ; Sets the page to be used for drawing, either the phyisical page (const
- ; pPhysical) or virtual page (const pVirtual). REMEMBER that if you draw
- ; to the virtual page, you need to display it (flipVPage()) before you can
- ; see it. Calling flipVPage() will copy the contents of the virtual page
- ; to the screen, regardless of which page is active, and does NOTHING else.
- ;
-
-
- sapStack struc
- dd ?,? ; room for registers
- dd ? ; caller
- aPage dd ? ; new active page
- sapStack ends
-
- public setActivePage
-
- setActivePage proc
-
- push ebp
- push edi
-
- mov ebp, esp
-
- mov eax, [ebp].aPage
- cmp eax, 0
- jne sapVPage
-
- mov eax, vidSeg
- mov curPage, eax
- jmp sapDone
-
- sapVPage:
-
- mov eax, virtPage
- mov curPage, eax
-
- sapDone:
-
- pop edi
- pop ebp
-
- ret 4
-
- setActivePage endp
-
-
- ;---------------------
- ; void flipVPage(void)
- ;---------------------
- ;
- ; flips the virtual page to the screen, displays what you have been drawing
- ; off screen.
-
-
- public flipVPage
-
- flipVPage proc
-
- push edi
- push esi
-
- call syncDisplay
-
- mov esi, virtPage
- mov edi, vidSeg
- mov ecx, 16000
-
- cld
- rep movsd
-
- pop esi
- pop edi
-
- ret
-
- flipVPage endp
-
-
- ; hline procedure used in poly filling, if you want to slow things down by
- ; calling it. The poly3 function makes use of an inline version of this
- ; procedure which eliminates the stack pushes and calls.
-
-
- hlStack struc
- dd ?,? ; room for regs
- dd ? ; caller
- hlcolor db ?,?,?,? ; color
- hly dd ? ; y
- hlx2 dd ? ; x2
- hlx1 dd ? ; x1
- hlStack ends
-
- public hline
-
- hline proc
-
- push ebp
- push edi
- mov ebp, esp
-
- mov eax, [ebp].hly
- mov ebx, 320
- mul ebx
-
- mov edi, curPage
-
- mov ecx, [ebp].hlx1
- mov ebx, [ebp].hlx2
-
- cmp ebx, ecx
- jg hlDraw
- xchg ebx, ecx
-
- hlDraw: add eax, ecx
- add edi, eax
-
- sub ebx, ecx
- mov ecx, ebx
- and ebx, 3
- shr ecx, 2
-
- mov ah, [ebp].hlcolor
- mov al, ah
- movzx edx, ax
- shl eax, 16
- or eax, edx
-
- cld
- rep stosd
- mov ecx, ebx
- rep stosb
-
- pop edi
- pop ebp
-
- ret 16
-
- hline endp
-
- ;----------------------------------------
- ; void setPixel(int x, int y, int color)
- ;----------------------------------------
- ;
- ; Sets the pixel at (x, y) to color (color). Does bounds checking to avoid
- ; the dreaded GP FAULT!
- ;
-
-
- spStack struc
- dd ?,? ; ebp, edi
- dd ? ; caller
- setpColor dd ? ; color of pixel
- setpY dd ? ; Y value
- setpX dd ? ; X value
- spStack ends
-
- public setPixel
-
- setPixel proc
-
- push ebp
- push edi
- mov ebp, esp
-
- mov eax, [ebp].setpY
- mov ecx, [ebp].setpX
-
- cmp eax, 0
- jl setPixDone
- cmp eax, 199
- jg setPixDone
- cmp ecx, 0
- jl setPixDone
- cmp ecx, 319
- jg setPixDone
-
- mov ebx, 320
- mul ebx
- add eax, ecx
-
- mov edi, eax
- add edi, curPage
-
- mov eax, [ebp].setpColor
- stosb
-
- setPixDone:
- pop edi
- pop ebp
-
- ret 12
-
- setPixel endp
-
- ;-----------------------
- ; void syncDisplay(void)
- ;-----------------------
- ;
- ; waits for the current vertical retrace to end, then waits for the start
- ; of the next one.
- ;
-
- public syncDisplay
-
- syncDisplay proc
-
- mov dx, 03DAh
-
- wait0:
- in al, dx
- test al, 08h
- jnz wait0
-
- wait1:
- in al, dx
- test al, 08h
- jz wait1
-
- ret
-
- syncDisplay endp
-
-
- ; a few basic mouse routines...I never implemented anything more in this
- ; library. Mice are easy, just refer to any interrupt listing for help.
-
- public initMouse
-
- initMouse proc
-
- mov ax, 0
- int 33h
-
- ret
-
- initMouse endp
-
- public showMouse
-
- showMouse proc
-
- mov ax, 1
- int 33h
-
- ret
-
- showMouse endp
-
- public hideMouse
-
- hideMouse proc
-
- mov ax, 2
- int 33h
-
- ret
-
- hideMouse endp
-
-
- ;----------------------------------------------------------------------------
- ; void poly3(int x1, int y1, int x2, int y2, int x3, int y3, int c);
- ;----------------------------------------------------------------------------
- ;
- ; Draws a clipped triangular polygon bounded by (x1,y1) (x2,y2) (x3,y3)
- ; in color c. This routine does NOT do shading!
- ;
-
-
- p3Stack struc
- dd ?,?,? ; room for regs
- dd ? ; caller
- p3color db ?,?,?,? ; color to fill
- p3y3 dd ? ; y3
- p3x3 dd ? ; x3
- p3y2 dd ? ; y2
- p3x2 dd ? ; x2
- p3y1 dd ? ; y1
- p3x1 dd ? ; x1
-
- p3Stack ends
-
- public poly3
-
- poly3 proc
-
- push ebp
- push edi
- push esi
-
- mov ebp, esp
-
- mov eax, [ebp].p3y1
- mov ebx, [ebp].p3y2
- mov ecx, [ebp].p3y3
-
- ; sort the points based on y values
-
- yComp1: cmp eax, ebx
- jg y2top
-
- mov yTop, eax
- mov edx, [ebp].p3x1
- mov xTop, edx
-
- mov yBot, ebx
- mov edx, [ebp].p3x2
- mov xBot, edx
-
- jmp yComp2
-
- y2top: mov yTop, ebx
- mov edx, [ebp].p3x2
- mov xTop, edx
-
- mov yBot, eax
- mov edx, [ebp].p3x1
- mov xBot, edx
-
- yComp2: cmp ecx, yTop
- jg yTopOK
-
- mov yTop, ecx
- mov edx, [ebp].p3x3
- mov xTop, edx
-
- cmp eax, ebx
- jg y2mid
-
- mov yMid, eax
- mov edx, [ebp].p3x1
- mov xMid, edx
-
- mov yBot, ebx
- mov edx, [ebp].p3x2
- mov xBot, edx
-
- jmp yCompDone
-
- y2mid: mov yMid, ebx
- mov edx, [ebp].p3x2
- mov xMid, edx
-
- mov yBot, eax
- mov edx, [ebp].p3x1
- mov xBot, edx
-
- jmp yCompDone
-
- yTopOK: cmp ecx, yBot
- jg ybBad
-
- mov yMid, ecx
- mov edx, [ebp].p3x3
- mov xMid, edx
-
- jmp yCompDone
-
- ybBad: mov eax, yBot
- mov ebx, xBot
-
- mov yMid, eax
- mov xMid, ebx
-
- mov yBot, ecx
- mov edx, [ebp].p3x3
- mov xBot, edx
-
- yCompDone:
-
- mov eax, yTop
- mov ebx, yBot
- cmp eax, 199
- jg fillDone
- cmp ebx, 0
- jl fillDone
-
- ; now calculate the x values at each scanline for the longest side.
-
- mov eax, xBot
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz edge1Horz ; skip the div if denominator = 0
- cmp eax, 0
- jge edge1Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp edge1Continue
-
- edge1Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp edge1Continue
-
- jmp edge2Start
-
- edge1Pos:
- xor edx, edx
- div ecx
-
- edge1Continue:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- edge1Loop:
-
- cmp esi, 0
- jl skipThisLine1
- cmp esi, 199
- jg edge2Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- skipThisLine1:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns edge1Loop
-
- ; calculate x values for next side
-
- edge2Start:
- mov eax, xBot
- mov ebx, xMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz edge2Horz
- cmp eax, 0
- jge edge2Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
- jmp edge2Continue
-
- edge2Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp edge2Continue
- jmp edge3Start
-
- edge2Pos:
- xor edx, edx
- div ecx
-
- edge2Continue:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xMid
- mov esi, yMid
-
- align 4
-
- edge2Loop:
-
- cmp esi, 0
- jl skipThisLine2
- cmp esi, 199
- jg edge3Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- skipThisLine2:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns edge2Loop
-
- ; calculate x values for last side
-
- edge3Start:
- mov eax, xMid
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz edge3Horz
- cmp eax, 0
- jge edge3Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp edge3Continue
-
- edge3Horz:
- ;xor eax, eax ; zero ratio
- ;xor edx, edx
- ;jmp edge3Continue
- jmp fillStart
-
- edge3Pos:
- xor edx, edx
- div ecx
-
- edge3Continue:
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- edge3Loop:
-
- cmp esi, 0
- jl skipThisLine3
- cmp esi, 199
- jg fillStart
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- skipThisLine3:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns edge3Loop
-
- ; time to fill...
-
- fillStart:
-
- mov eax, yTop
- mov ebx, yBot
-
- cmp eax, 0
- jge checkBot
- xor eax, eax
- mov yTop, eax
-
- checkBot:
- cmp ebx, 199
- jle fillNOW
- mov ebx, 199
- mov yBot, ebx
-
- fillNOW:
- lea esi, lEdge
- lea edi, rEdge
-
- mov dl, [ebp].p3color
- mov dh, dl
- movzx edx, dx
- mov eax, edx
- shl eax, 16
- or edx, eax
- mov rhlColor, edx
-
- mov ecx, yTop
- mov ebx, yBot
- shl ecx, 2
- add esi, ecx
- add edi, ecx
- shr ecx, 2
-
- align 4
-
- fillME: push ecx
-
- ; another way to draw the hline, with register calls rather than
- ; stack pushes to improve speed
- ;
- ; ON ENTRY
- ; [esi] = x1
- ; [edi] = x2
- ; ecx = y
- ; rhlColor = color to fill line with as a dword, that is, to draw
- ; a line of color 1, rhlColor would be 01010101
-
- ;public regHline
-
- mov eax, 320
- xor edx, edx
- mul ecx
-
- mov ecx, [esi]
- mov ebx, [edi]
-
- cmp ebx, ecx
- jg rhlDraw
- xchg ebx, ecx
-
- rhlDraw:
-
- cmp ecx, 319
- jg nextLine
-
- cmp ebx, 0
- jl nextLine
-
- checkX2:
- cmp ebx, 319
- jle checkX1
- mov ebx, 319
-
- checkX1:
- cmp ecx, 0
- jge x1OKToo
- xor ecx, ecx
-
- x1OKToo:
- push edi
- add eax, ecx
- mov edi, curPage
- add edi, eax
-
- sub ebx, ecx
- mov ecx, ebx
- and ebx, 3
- shr ecx, 2
-
- mov eax, rhlColor
-
- cld
- rep stosd
- mov ecx, ebx
- rep stosb
-
- pop edi
-
- ; end of the rhline proc (used to be a proc anyway...)
-
- nextLine:
- pop ecx
-
- add esi, 4
- add edi, 4
- inc ecx
- cmp ecx, yBot
- jg fillDone
- jmp fillME
-
- fillDone:
-
- pop esi
- pop edi
- pop ebp
-
- ret 28
-
- poly3 endp
-
- ;----------------------------
- ; void clearScreen(int color)
- ;----------------------------
- ;
- ; fills the screen with color (color). This is perhaps the most difficult
- ; thing I've ever written...heheh
- ;
-
- csStack struc
-
- dd ?,? ; ebp, edi
- dd ? ; caller
- csColor db ?,?,?,? ; color
-
- csStack ends
-
- public clearScreen
-
- clearScreen proc
-
- push ebp
- push edi
-
- mov ebp, esp
-
- mov edi, curPage
- mov ecx, 16000
- mov al, [ebp].csColor
- mov ah, al
- movzx edx, ax
- shl eax, 16
- or eax, edx
-
- rep stosd
-
- pop edi
- pop ebp
-
- ret 4
-
- clearScreen endp
-
-
- ; Palette routines courtesy of Matt Pritchard (MODEX). Something went wrong
- ; with the load_dac_registers routine in the conversion to 32 bit and pmode,
- ; and I haven't found the time to correct it yet...what a lazy bum I am!
- ; I've been using repeated calls to the set_dac_register routine instead...
-
- ;=================================================
- ;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%)
- ;=================================================
- ;
- ; Sets a single (RGB) Vga Palette Register
- ;
- ; ENTRY: Register = The DAC # to modify (0-255)
- ; Red = The new Red Intensity (0-63)
- ; Green = The new Green Intensity (0-63)
- ; Blue = The new Blue Intensity (0-63)
- ;
- ; EXIT: No meaningful values returned
- ;
-
- SDR_STACK STRUC
- DD ? ; eBP
- DD ? ; Caller
- SDR_Blue DB ?,?,?,? ; Blue Data Value
- SDR_Green DB ?,?,?,? ; Green Data Value
- SDR_Red DB ?,?,?,? ; Red Data Value
- SDR_Register DB ?,?,?,? ; Palette Register #
- SDR_STACK ENDS
-
- PUBLIC SET_DAC_REGISTER
-
- SET_DAC_REGISTER PROC
-
- PUSH eBP ; Save BP
- MOV eBP, eSP ; Set up Stack Frame
-
- ; Select which DAC Register to modify
-
- mov dx, 03C8h
- mov al, [eBP].SDR_Register
- out dx, al
-
- MOV DX, 03C9h ; Dac Data Register
- mov al, [eBP].SDR_Red ; Set Red Intensity
- out dx, al
- mov al, [eBP].SDR_Green ; Set Green Intensity
- out dx, al
- mov al, [eBP].SDR_Blue ; Set Blue Intensity
- out dx, al
-
- POP eBP ; Restore Registers
- RET 16 ; Exit & Clean Up Stack
-
- SET_DAC_REGISTER ENDP
-
-
- ;===========================================================
- ;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%)
- ;===========================================================
- ;
- ; Sets a Block of Vga Palette Registers
- ;
- ; ENTRY: PalData = Far Pointer to Block of palette data
- ; StartReg = First Register # in range to set (0-255)
- ; EndReg = Last Register # in Range to set (0-255)
- ; Sync = Wait for Vertical Retrace Flag (Boolean)
- ;
- ; EXIT: No meaningful values returned
- ;
- ; NOTES: PalData is a linear array of 3 byte Palette values
- ; in the order: Red (0-63), Green (0-63), Blue (0-63)
- ;
-
- LDR_STACK STRUC
- DD ?,? ; EBP, ESI
- DD ? ; Caller
- LDR_Sync DW ?,? ; Vertical Sync Flag
- LDR_EndReg DB ?,?,?,? ; Last Register #
- LDR_StartReg DB ?,?,?,? ; First Register #
- LDR_PalData DD ? ; Far Ptr to Palette Data
- LDR_STACK ENDS
-
- PUBLIC LOAD_DAC_REGISTERS
-
- LOAD_DAC_REGISTERS PROC
-
- PUSH ebp
- push esi ; Save Registers
- mov ebp, esp ; Set up Stack Frame
-
- mov AX, [BP].LDR_Sync ; Get Vertical Sync Flag
- or AX, AX ; is Sync Flag = 0?
- jz @LDR_Load ; if so, skip call
-
- call syncDisplay ; wait for vsync
-
- ; Determine register #'s, size to copy, etc
-
- @LDR_Load:
-
- mov esi, [BP].LDR_PalData ; DS:SI -> Palette Data
- mov DX, 03C8h ; DAC register # selector
-
- xor AX, ax
- xor BX, bx ; Clear for byte loads
- mov AL, [BP].LDR_StartReg ; Get Start Register
- mov BL, [BP].LDR_EndReg ; Get End Register
-
- sub BX, AX ; BX = # of DAC registers -1
- inc BX ; BX = # of DAC registers
- mov CX, BX ; CX = # of DAC registers
- add CX, BX ; CX = " " * 2
- add CX, BX ; CX = " " * 3
- cld ; Block OUTs forward
- out DX, AL ; set up correct register #
-
- ; Load a block of DAC Registers
-
- mov DX, 03C9h ; Dac Data Register
-
- rep outsb ; block set DAC registers
-
- POP esi
- pop ebp ; Restore Registers
-
- ret 20 ; Exit & Clean Up Stack
-
- LOAD_DAC_REGISTERS ENDP
-
- ;----------------------------------------------------
- ; void ghline(int x1, int c1, int x2, int c2, int y);
- ;----------------------------------------------------
- ;
- ; draws a horizontal line from (x1, y) to (x2, y) and interpolates colors
- ; (byte granularity) from c1 to c2 in the process. This is used to fill
- ; polygons in the gpoly3 routine. I really should make this an inline
- ; procedure like I did with hline, but the call is so much more complex...
- ; I figured it would take just about as long either way. Clipping too...
- ;
-
-
- ghlStack struc
-
- dd ?,?,? ; ebp esi edi
- dd ? ; caller
- ghly dd ? ; y
- ghlc2 dd ? ; c2
- ghlx2 dd ? ; x2
- ghlc1 dd ? ; c1
- ghlx1 dd ? ; x1
-
- ghlStack ends
-
- public gHline
-
- gHline proc ; gouraud hline routine
-
- push ebp
- push esi
- push edi
- mov ebp, esp
-
- mov eax, [ebp].ghly
- mov ebx, 320
- mul ebx
-
- mov edi, curPage
-
- mov ecx, [ebp].ghlx1
- mov ebx, [ebp].ghlx2
- mov esi, [ebp].ghlc1
- mov edx, [ebp].ghlc2
-
- cmp ebx, ecx
- jg ghlDraw
- xchg ebx, ecx
- xchg esi, edx
-
- ghlDraw:
- mov [ebp].ghlc2, edx
-
- cmp ecx, 0
- jge ghlx1ok
- mov ecx, 0
-
- ghlx1ok:
- cmp ecx, 320
- jge ghldone
-
- cmp ebx, 319
- jl ghlx2ok
- mov ebx, 319
-
- ghlx2ok:
- cmp ebx, 0
- jl ghldone
-
-
- add eax, ecx
- add edi, eax
-
- sub ebx, ecx
- mov ecx, ebx
-
- jecxz ghlIHATESHORTJUMPS
-
- ; and ebx, 3
- ; shr ecx, 2
-
-
-
-
- mov eax, edx
- sub eax, esi
- shl eax, 8 ; dc *= 256
- xor edx, edx
-
- cmp eax, 0
- jl ghlNeg
- div ebx ; get dcdx
- jmp ghlGoOn
-
- ghlIHATESHORTJUMPS:
- jmp ghlDone
-
- ghlNeg:
- neg eax
- div ebx
- neg eax
-
- ghlGoOn:
- mov edx, eax ; edx = dcdx * 256
- mov ebx, esi ; eax = c1
- shl ebx, 8 ; ebx *= 256
-
- ;mov esi, ecx
- ;and esi, 7
- ;shr ecx, 3
-
- cld
- align 4
-
- ghlLoop:
- jcxz ghlMod
-
- mov [edi], bh
- inc edi
- add ebx, edx
-
- dec ecx
- jmp ghlLoop
-
- ghlMod:
- ;mov ecx, esi
- ;rep stosb
-
- ghlDone:
- pop edi
- pop esi
- pop ebp
-
- ret 20
-
-
- gHline endp
-
-
- ;----------------------------------------------------------------------------
- ; void gpoly3(int x1, int y1, int c1, int x2, int y2, int c2, int x3, int y3,
- ; int c3);
- ;----------------------------------------------------------------------------
- ;
- ; Draws a fully clipped gouraud shaded polygon at the given coordinates and
- ; colors. If you don't understand the concept behind gouraud shading, this
- ; is not the place to learn. Send email.
- ;
-
-
- gp3Stack struc
- dd ?,?,? ; room for regs
- dd ? ; caller
- gp3c3 dd ? ; c3
- gp3y3 dd ? ; y3
- gp3x3 dd ? ; x3
- gp3c2 dd ? ; c2
- gp3y2 dd ? ; y2
- gp3x2 dd ? ; x2
- gp3c1 dd ? ; c1
- gp3y1 dd ? ; y1
- gp3x1 dd ? ; x1
-
- gp3Stack ends
-
- public gpoly3
-
- gpoly3 proc
-
- push ebp
- push edi
- push esi
-
- mov ebp, esp
-
- mov eax, [ebp].gp3y1
- mov ebx, [ebp].gp3y2
- mov ecx, [ebp].gp3y3
-
- ; sort the points based on y values
-
- gyComp1:
- cmp eax, ebx
- jg gy2top
-
- mov yTop, eax
- mov edx, [ebp].gp3x1
- mov xTop, edx
- mov edx, [ebp].gp3c1
- mov cTop, edx
-
- mov yBot, ebx
- mov edx, [ebp].gp3x2
- mov xBot, edx
- mov edx, [ebp].gp3c2
- mov cBot, edx
-
- jmp gyComp2
-
- gy2top: mov yTop, ebx
- mov edx, [ebp].gp3x2
- mov xTop, edx
- mov edx, [ebp].gp3c2
- mov cTop, edx
-
- mov yBot, eax
- mov edx, [ebp].gp3x1
- mov xBot, edx
- mov edx, [ebp].gp3c1
- mov cBot, edx
-
- gyComp2:
- cmp ecx, yTop
- jg gyTopOK
-
- mov yTop, ecx
- mov edx, [ebp].gp3x3
- mov xTop, edx
- mov edx, [ebp].gp3c3
- mov cTop, edx
-
- cmp eax, ebx
- jg gy2mid
-
- mov yMid, eax
- mov edx, [ebp].gp3x1
- mov xMid, edx
- mov edx, [ebp].gp3c1
- mov cMid, edx
-
- mov yBot, ebx
- mov edx, [ebp].gp3x2
- mov xBot, edx
- mov edx, [ebp].gp3c2
- mov cBot, edx
-
-
- jmp gyCompDone
-
- gy2mid: mov yMid, ebx
- mov edx, [ebp].gp3x2
- mov xMid, edx
- mov edx, [ebp].gp3c2
- mov cMid, edx
-
- mov yBot, eax
- mov edx, [ebp].gp3x1
- mov xBot, edx
- mov edx, [ebp].gp3c1
- mov cBot, edx
-
- jmp gyCompDone
-
- gyTopOK:
- cmp ecx, yBot
- jg gybBad
-
- mov yMid, ecx
- mov edx, [ebp].gp3x3
- mov xMid, edx
- mov edx, [ebp].gp3c3
- mov cMid, edx
-
- jmp gyCompDone
-
- gybBad: mov eax, yBot
- mov ebx, xBot
- mov edx, cBot
-
- mov yMid, eax
- mov xMid, ebx
- mov cMid, edx
-
- mov yBot, ecx
- mov edx, [ebp].gp3x3
- mov xBot, edx
- mov edx, [ebp].gp3c3
- mov cBot, edx
-
-
- gyCompDone:
-
- mov eax, yTop
- mov ebx, yBot
- cmp eax, 199
- jg gfillDone
- cmp ebx, 0
- jl gfillDone
-
- ; now calculate the x values at each scanline for the longest side.
-
- mov eax, xBot
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge1Horz ; skip the div if denominator = 0
- cmp eax, 0
- jge gedge1Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge1Continue
-
- gedge1Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge1Continue
-
- jmp gedge2Start
-
- gedge1Pos:
- xor edx, edx
- div ecx
-
- gedge1Continue:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- gedge1Loop:
-
- cmp esi, 0
- jl gskipThisLine1
- cmp esi, 199
- jg gedge2Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine1:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge1Loop
-
- ; calculate x values for next side
-
- gedge2Start:
- mov eax, xBot
- mov ebx, xMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gedge2Horz
- cmp eax, 0
- jge gedge2Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
- jmp gedge2Continue
-
- gedge2Horz:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge2Continue
- jmp gedge3Start
-
- gedge2Pos:
- xor edx, edx
- div ecx
-
- gedge2Continue:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xMid
- mov esi, yMid
-
- align 4
-
- gedge2Loop:
-
- cmp esi, 0
- jl gskipThisLine2
- cmp esi, 199
- jg gedge3Start
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine2:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge2Loop
-
- ; calculate x values for last side
-
- gedge3Start:
- mov eax, xMid
- mov ebx, xTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge3Horz
- cmp eax, 0
- jge gedge3Pos
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge3Continue
-
- gedge3Horz:
- ;xor eax, eax ; zero ratio
- ;xor edx, edx
- ;jmp gedge3Continue
- jmp gcolorStartc
-
- gedge3Pos:
- xor edx, edx
- div ecx
-
- gedge3Continue:
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rEdge
- add edi, ebx
-
- xor ebx, ebx
- mov edx, xTop
- mov esi, yTop
-
- align 4
-
- gedge3Loop:
-
- cmp esi, 0
- jl gskipThisLine3
- cmp esi, 199
- jg gcolorStartc
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine3:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge3Loop
-
- gcolorStartc:
-
- ; now calculate the color values at each scanline for the longest side.
-
- mov eax, cBot
- mov ebx, cTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge1Horzc ; skip the div if denominator = 0
- cmp eax, 0
- jge gedge1Posc
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge1Continuec
-
- gedge1Horzc:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge1Continuec
-
- jmp gedge2Startc
-
- gedge1Posc:
- xor edx, edx
- div ecx
-
- gedge1Continuec:
- mov ecx, yBot
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, lColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cTop
- mov esi, yTop
-
- align 4
-
- gedge1Loopc:
-
- cmp esi, 0
- jl gskipThisLine1c
- cmp esi, 199
- jg gedge2Startc
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine1c:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge1Loopc
-
- ; calculate x values for next side
-
- gedge2Startc:
- mov eax, cBot
- mov ebx, cMid
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yBot
- mov edx, yMid
- sub ecx, edx
-
- jecxz gedge2Horzc
- cmp eax, 0
- jge gedge2Posc
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
- jmp gedge2Continuec
-
- gedge2Horzc:
- ;xor eax, eax
- ;xor edx, edx
- ;jmp gedge2Continuec
- jmp gedge3Startc
-
- gedge2Posc:
- xor edx, edx
- div ecx
-
- gedge2Continuec:
- mov ecx, yBot
- mov ebx, yMid
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cMid
- mov esi, yMid
-
- align 4
-
- gedge2Loopc:
-
- cmp esi, 0
- jl gskipThisLine2c
- cmp esi, 199
- jg gedge3Startc
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine2c:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge2Loopc
-
- ; calculate x values for last side
-
- gedge3Startc:
- mov eax, cMid
- mov ebx, cTop
- sub eax, ebx
- shl eax, 16
-
- mov ecx, yMid
- mov edx, yTop
- sub ecx, edx
-
- jecxz gedge3Horzc
- cmp eax, 0
- jge gedge3Posc
-
- neg eax
- xor edx, edx
- div ecx
- neg eax
-
- jmp gedge3Continuec
-
- gedge3Horzc:
- ;xor eax, eax ; zero ratio
- ;xor edx, edx
- ;jmp gedge3Continuec
- jmp gfillStart
-
- gedge3Posc:
- xor edx, edx
- div ecx
-
- gedge3Continuec:
- mov ecx, yMid
- mov ebx, yTop
- sub ecx, ebx
-
- shl ebx, 2
- lea edi, rColor
- add edi, ebx
-
- xor ebx, ebx
- mov edx, cTop
- mov esi, yTop
-
- align 4
-
- gedge3Loopc:
-
- cmp esi, 0
- jl gskipThisLine3c
- cmp esi, 199
- jg gfillStart
-
- ror ebx, 16
- add dx, bx
- movsx edx, dx
- rol ebx, 16
- movzx ebx, bx
- mov [edi], edx
-
- gskipThisLine3c:
- add ebx, eax
- add edi, 4
- inc esi
- dec ecx
- jns gedge3Loopc
-
-
- ; time to fill...
-
- gfillStart:
-
- mov eax, yTop
- mov ebx, yBot
-
- cmp eax, 0
- jge gcheckBot
- xor eax, eax
- mov yTop, eax
-
- gcheckBot:
- cmp ebx, 199
- jle gfillNOW
- mov ebx, 199
- mov yBot, ebx
-
- gfillNOW:
- lea esi, lEdge
- lea edi, rEdge
-
- lea eax, lColor
- lea edx, rColor
-
- mov ecx, yTop
- mov ebx, yBot
- shl ecx, 2
-
- add esi, ecx
- add edi, ecx
- add eax, ecx
- add edx, ecx
-
- shr ecx, 2
-
- align 4
-
- gfillME: push ecx
-
-
- grhlDraw:
-
- cmp ecx, 319
- jg gnextLine
-
- cmp ebx, 0
- jl gnextLine
-
- gcheckX2:
- cmp ebx, 319
- jle gcheckX1
- mov ebx, 319
-
- gcheckX1:
- cmp ecx, 0
- jge gx1OKToo
- xor ecx, ecx
-
- gx1OKToo:
- push esi
- push eax
- push edi
- push edx
-
- push [esi]
- push [eax]
- push [edi]
- push [edx]
- push ecx
-
- call gHline
-
- pop edx
- pop edi
- pop eax
- pop esi
-
- gnextLine:
- pop ecx
-
- add esi, 4
- add edi, 4
- add eax, 4
- add edx, 4
- inc ecx
- cmp ecx, yBot
- jg gfillDone
- jmp gfillME
-
- gfillDone:
-
- pop esi
- pop edi
- pop ebp
-
- ret 36
-
- gpoly3 endp
-
-
- ;--------------------------------------------------------------------
- ; void tDrawBitmap(char *image, int x, int y, int width, int height);
- ;--------------------------------------------------------------------
- ;
- ; draws a bitmapt to the screen, with color 0 transparent. Full clipping
- ; is done as an added bonus...
- ;
-
- tdbStack STRUC
-
- dd ?,?,? ; ebp, esi, edi
- dd ? ; caller
- tdbHeight dd ?
- tdbWidth dd ?
- tdbY dd ?
- tdbX dd ?
- tdbImage dd ?
-
- tdbStack ENDS
-
- public tDrawBitmap
-
- tDrawBitmap proc
-
- push edi
- push esi
- push ebp
-
- mov ebp, esp
-
- mov eax, 0
- mov sPos, eax
- mov xOffset, 0
- mov yOffset, 0
-
- mov esi, [ebp].tdbImage
- mov edi, curPage
- mov ecx, [ebp].tdbY
- mov eax, 320
- mul ecx
- mov edx, [ebp].tdbX
- add eax, edx
- mov dPos, eax
-
- mov ebx, [ebp].tdbWidth
- mov eax, [ebp].tdbHeight
- mov oWidth, ebx
- mov nWidth, ebx
- mov oHeight, eax
- mov nHeight, eax
-
- ; clipping action...
-
- cmp edx, 0
- jl tdbXNeg
-
- tdbCheckY:
- cmp ecx, 0
- jl tdbYNeg
-
- jmp tdbContinue
-
- tdbXNeg:
- neg edx
- cmp edx, ebx
- jg tdbDone ; bitmap is off screen if -x > width
- mov xOffset, edx ; store the offset
- neg edx ; back to negative...
- add nWidth, edx
-
- jmp tdbCheckY
-
- tdbYNeg:
- neg ecx
- cmp ecx, eax
- jge tdbDone ; bitmap is off screen if -y > height
- ;neg ecx
- ;add ecx, eax
- sub nHeight, ecx
- inc ecx
-
- tdbFixY:
- dec ecx
- cmp ecx, 0
- jle tdbContinue
- add dPos, 320 ; go to next line on screen
- add sPos, ebx ; go to next line in source
- jmp tdbFixY
-
- tdbContinue:
-
- mov ecx, [ebp].tdbY ; recharge ecx
-
- cmp ecx, 200 ;
- jg tdbDone
-
- cmp edx, 320 ;
- jg tdbDone
-
- add ebx, edx
- cmp ebx, 320 ;
- jg tdbXTooBig
-
- tdbCheckY2:
- add eax, ecx
- cmp eax, 200 ;
- ;cmp nHeight, 200
- jge tdbYTooBig
-
- jmp tdbClipDone
-
- tdbXTooBig:
- mov nWidth, ebx
- cmp edx, 0
- jge tdbXPos
-
- cmp nWidth, 320
- jl tdbClipDone
- mov nWidth, 320
- jmp tdbCheckY2
-
- ;mov ebx, 320
- ;sub ebx, edx
- ;cmp ebx, 320
- ;jl tdbXTooBig2
- ;mov ebx, 320
-
- tdbXPos:
- mov ebx, 320
- sub ebx, edx
- mov nWidth, ebx
- jmp tdbCheckY2
-
- tdbXTooBig2:
- ;mov nWidth, ebx
- ;jmp tdbCheckY2
-
- ;sub edx, 320 ;
- ;sub ebx, edx ; get new 'width'
- ;mov nWidth, ebx
- ;jmp tdbCheckY2
-
- tdbYTooBig:
- cmp ecx, 0
- jge tdbYPos
-
- cmp nHeight, 200
- jl tdbClipDone
- mov nHeight, 200
- jmp tdbClipDone
- ;cmp eax, 0
- ;jg tdbYTooBigPos
- ;mov eax, 200
- ;sub eax, ecx
- ;cmp eax, 200
- ;jl tdbYTooBig3
- ;mov eax, 200
- ;jmp tdbYTooBig3
-
- tdbYPos:
- mov eax, 200
- sub eax, ecx
- mov nHeight, eax
- jmp tdbClipDone
-
-
- tdbYTooBig3:
- ;mov nHeight, eax
- ;jmp tdbClipDone
-
- ;sub ecx, 200 ;
- ;sub eax, ecx ; get new 'height'
- ;mov nHeight, eax
- ;jmp tdbClipDone
-
- tdbClipDone:
-
- mov ecx, nHeight ; get 'height'
- cld
- mov edx, xOffset
- add sPos, edx
- add dPos, edx
-
- align 4
-
- tdbDrawLoop:
- mov esi, [ebp].tdbImage
- add esi, sPos
-
- mov edi, curPage
- add edi, dPos
-
- mov ebx, ecx
- mov ecx, nWidth
- mov edx, xOffset
- ;sub ecx, edx
-
- align 4
-
- tdbRowLoop:
-
- cmp ecx, 4
- jl tdbMod
-
- lodsd
-
- test al, 0FFh
- jz tdbPix2
- stosb
- dec edi
-
- tdbPix2:
- inc edi
- shr eax, 8
- test al, 0FFh
- jz tdbPix3
- stosb
- dec edi
-
- tdbPix3:
- inc edi
- shr eax, 8
- test al, 0FFh
- jz tdbPix4
- stosb
- dec edi
-
- tdbPix4:
- inc edi
- shr eax, 8
- test al, 0FFh
- jz tdbNextDW
- stosb
- dec edi
-
- tdbNextDW:
- inc edi
- sub ecx, 4
- jmp tdbRowLoop
-
- tdbMod:
- jecxz tdbRowDone
- lodsb
- test al, 0FFh
- jz tdbMod2
- stosb
- dec edi
-
- tdbMod2:
- inc edi
- dec ecx
- jecxz tdbRowDone
- lodsb
- test al, 0FFh
- jz tdbMod3
- stosb
- dec edi
-
- tdbMod3:
- inc edi
- dec ecx
- jecxz tdbRowDone
- lodsb
- test al, 0FFh
- jz tdbRowDone
- stosb
- dec edi
-
- tdbRowDone:
- inc edi
- mov ecx, ebx
- dec ecx
- mov ebx, oWidth
- add sPos, ebx
- add dPos, 320
- ; mov ebx, xOffset
- ; add dPos, ebx
- ; add sPos, ebx
-
- cmp ecx, 0
- jle tdbDone
-
- ;jecxz tdbDone
- jmp tdbDrawLoop
-
- tdbDone:
-
- pop ebp
- pop esi
- pop edi
-
- ret 20
-
-
- tDrawBitmap endp
-
-
- ;-------------------------------------------------------------------
- ; void drawBitmap(char *image, int x, int y, int width, int height);
- ;-------------------------------------------------------------------
- ;
- ; draws a bitmap to the screen. Full clipping once again...
- ;
-
-
- dbStack STRUC
-
- dd ?,?,? ; ebp, esi, edi
- dd ? ; caller
- dbHeight dd ?
- dbWidth dd ?
- dbY dd ?
- dbX dd ?
- dbImage dd ?
-
- dbStack ENDS
-
- public drawBitmap
-
- drawBitmap proc
-
- push edi
- push esi
- push ebp
-
- mov ebp, esp
-
- mov eax, 0
- mov sPos, eax
- mov xOffset, 0
- mov yOffset, 0
-
- mov esi, [ebp].dbImage
- mov edi, curPage
- mov ecx, [ebp].dbY
- mov eax, 320
- mul ecx
- mov edx, [ebp].dbX
- add eax, edx
- mov dPos, eax
-
- mov ebx, [ebp].dbWidth
- mov eax, [ebp].dbHeight
- mov oWidth, ebx
- mov nWidth, ebx
- mov oHeight, eax
- mov nHeight, eax
-
- ; clipping action...
-
- cmp edx, 0
- jl dbXNeg
-
- dbCheckY:
- cmp ecx, 0
- jl dbYNeg
-
- jmp dbContinue
-
- dbXNeg:
- neg edx
- cmp edx, ebx
- jg dbDone ; bitmap is off screen if -x > width
- mov xOffset, edx ; store the offset
- neg edx ; back to negative...
- add nWidth, edx
-
- jmp dbCheckY
-
- dbYNeg:
- neg ecx
- cmp ecx, eax
- jge dbDone ; bitmap is off screen if -y > height
- ;neg ecx
- ;add ecx, eax
- sub nHeight, ecx
- inc ecx
-
- dbFixY:
- dec ecx
- cmp ecx, 0
- jle dbContinue
- add dPos, 320 ; go to next line on screen
- add sPos, ebx ; go to next line in source
- jmp dbFixY
-
- dbContinue:
-
- mov ecx, [ebp].dbY ; recharge ecx
-
- cmp ecx, 200 ;
- jg dbDone
-
- cmp edx, 320 ;
- jg dbDone
-
- add ebx, edx
- cmp ebx, 320 ;
- jg dbXTooBig
-
- dbCheckY2:
- add eax, ecx
- cmp eax, 200 ;
- ;cmp nHeight, 200
- jge dbYTooBig
-
- jmp dbClipDone
-
- dbXTooBig:
- mov nWidth, ebx
- cmp edx, 0
- jge dbXPos
-
- cmp nWidth, 320
- jl dbClipDone
- mov nWidth, 320
- jmp dbCheckY2
-
- ;mov ebx, 320
- ;sub ebx, edx
- ;cmp ebx, 320
- ;jl dbXTooBig2
- ;mov ebx, 320
-
- dbXPos:
- mov ebx, 320
- sub ebx, edx
- mov nWidth, ebx
- jmp dbCheckY2
-
- dbXTooBig2:
- ;mov nWidth, ebx
- ;jmp dbCheckY2
-
- ;sub edx, 320 ;
- ;sub ebx, edx ; get new 'width'
- ;mov nWidth, ebx
- ;jmp dbCheckY2
-
- dbYTooBig:
- cmp ecx, 0
- jge dbYPos
-
- cmp nHeight, 200
- jl dbClipDone
- mov nHeight, 200
- jmp dbclipDone
- ;cmp eax, 0
- ;jg dbYTooBigPos
- ;mov eax, 200
- ;sub eax, ecx
- ;cmp eax, 200
- ;jl dbYTooBig3
- ;mov eax, 200
- ;jmp dbYTooBig3
-
- dbYPos:
- mov eax, 200
- sub eax, ecx
- mov nHeight, eax
- jmp dbclipDone
-
-
- dbYTooBig3:
- ;mov nHeight, eax
- ;jmp dbClipDone
-
- ;sub ecx, 200 ;
- ;sub eax, ecx ; get new 'height'
- ;mov nHeight, eax
- ;jmp dbClipDone
-
- dbClipDone:
-
- mov ecx, nHeight ; get 'height'
- cld
- mov edx, xOffset
- add sPos, edx
- add dPos, edx
-
- align 4
-
- dbDrawLoop:
- mov esi, [ebp].dbImage
- add esi, sPos
-
- mov edi, curPage
- add edi, dPos
-
- mov ebx, ecx
- mov ecx, nWidth
- mov edx, xOffset
- ;sub ecx, edx
-
- dbRowLoop:
-
- mov edx, ecx
- shr ecx, 2
- and edx, 3
-
- cmp ecx, 0
- jle dbMod
-
- rep movsd
-
- dbMod:
- mov ecx, edx
- rep movsb
-
-
- dbRowDone:
- mov ecx, ebx
- dec ecx
- mov ebx, oWidth
- add sPos, ebx
- add dPos, 320
- ; mov ebx, xOffset
- ; add dPos, ebx
- ; add sPos, ebx
-
- cmp ecx, 0
- jle dbDone
-
- ;jecxz dbDone
- jmp dbDrawLoop
-
- dbDone:
-
- pop ebp
- pop esi
- pop edi
-
- ret 20
-
-
- drawBitmap endp
-
-
- end ; end of code (the ONLY) segment
-
-